#include "trigger.h"

Trigger::Trigger()
    : m_written( 0 )
{
    int32_t ret = ::pipe( m_pipes );
    if( ret < 0 )
    {
        perror( "open pipe: " );
        m_pipes[0] = m_pipes[1] = -1;
        return;
    }
    // readfd = m_pipes[0]
    // writefd = m_pipes[1]
    fcntl( m_pipes[0], F_SETFL, O_NONBLOCK );
    fcntl( m_pipes[1], F_SETFL, O_NONBLOCK );
    fcntl( m_pipes[0], F_SETFL, O_NOATIME );
}

Trigger::~Trigger() throw()
{
    close( m_pipes[0] );
    close( m_pipes[1] );
}

Trigger & Trigger::instance()
{
    static Trigger notify;
    return notify;
}

void Trigger::notify()
{
    Guard<Thread_Mutex> monitor( m_mutex );
    if( m_written <= 0 )
    {
        ++m_written;
        char buf = 'k';
        //debug_output( "%s", "send k byte notify" );
        write( m_pipes[1], &buf, sizeof(buf) );
    }
}

int32_t Trigger::drain()
{
    Guard<Thread_Mutex> monitor( m_mutex );
    while( m_written > 0 )
    {
        char buf[64];
        int32_t ret = read( m_pipes[0], buf, sizeof(buf) );
        if( ret > 0 )
        {
            //debug_output( "recv (%d) bytes notify", ret );
            m_written -= ret;
        }
        else
            break;
    }
    return m_written;
}

int32_t Trigger::get_readfd() const
{
    return m_pipes[0];
}


